package societyGames.utility
{
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;

	public class XmlUtility
	{
		public static function getRequiredInt(xml:XML, elementName:String):int
		{
			var number:Number = getRequiredNumber(xml, elementName);
			if (number == int(number))
			{
				return int(number);
			}
			else
			{
				throw new ArgumentError("Invalid required element: " + elementName + ": " + xml.toXMLString()); 
			}
		}
		
		public static function getRequiredNumber(xml:XML, elementName:String):Number
		{
			var number:Number = Number(getRequiredElement(xml, elementName));
			if (isNaN(number))
			{
				throw new ArgumentError("Missing or invalid required element: " + elementName + ": " + xml.toXMLString());
			}
			return number;
		}
		
		public static function getRequiredElement(xml:XML, elementName:String):String
		{
			var value:String = getOptionalElement(xml, elementName);
			if (value == null)
			{
				throw new ArgumentError("Missing required element: " + elementName + ": " + xml.toXMLString());
			}
			return value;
		}
		
		public static function getOptionalElement(xml:XML, elementName:String):String
		{
			if (xml.hasOwnProperty(elementName))
			{
				var element:Object = xml[elementName];
				if (element is XMLList)
				{
					var elementXML:XML = XMLList(element)[0];
					if (elementXML.hasSimpleContent())
					{
						return XMLList(element)[0].toString();
					}
					else
					{
						throw new ArgumentError("Requested element is not simple content: " + elementName + ": " + xml.toXMLString()); 
					}
				}
				else
				{
					return String(element);
				}
			}
			return null;
		}
		
		public static function getRequiredNode(xml:XML, nodeName:String):XML
		{
			var xml:XML = getOptionalNode(xml, nodeName);
			if (xml != null)
			{
				return xml;
			}
			else
			{
				throw new ArgumentError("Requested node: " + nodeName + " not found: " + xml.toXMLString());
			}
		}
		
		public static function getOptionalNode(xml:XML, nodeName:String):XML
		{
			if (xml.hasOwnProperty(nodeName))
			{
				return xml[nodeName][0];
			}
			else
			{
				return null;
			}
		}
		
		public static function createCDATA(value:String):XML
		{
			var xml:XML = new XML("<![CDATA[" + value + "]]>");
			return xml;
		}
		
		public static function writeXML(xml:XML, file:File):void
		{
			var fileStream:FileStream = new FileStream();
			fileStream.open(file, FileMode.WRITE);
			try
			{
				var outputString:String = '<?xml version="1.0" encoding="utf-8"?>\n';
				outputString += xml.toXMLString();
				outputString = outputString.replace(/\n/g, File.lineEnding);
				fileStream.writeUTFBytes(outputString);
			}
			finally
			{
				fileStream.close();
			}
		}
		
		public static function readXML(file:File):XML
		{
			var fileStream:FileStream = new FileStream();
			fileStream.open(file, FileMode.READ);
			try
			{
				var xml:XML = XML(fileStream.readUTFBytes(fileStream.bytesAvailable));
				return xml;
			}
			finally
			{
				fileStream.close();
			}
			return null;
		}
	}
}